/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package familytree.negocio.bo;

import familytree.negocio.IEventoProcessor;
import familytree.persistencia.dao.DAOFactory;
import familytree.persistencia.dao.EventoDAO;
import familytree.persistencia.pojos.Evento;
import familytree.persistencia.pojos.Nodo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import net.fortuna.ical4j.data.CalendarOutputter;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.Recur;
import net.fortuna.ical4j.model.ValidationException;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.property.CalScale;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.RRule;
import net.fortuna.ical4j.model.property.Version;
import net.fortuna.ical4j.util.UidGenerator;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

/**
 *
 * @author Jose
 */
public class EventoBO  implements IEventoProcessor{
    private DAOFactory dAOFactory = DAOFactory.instance(DAOFactory.HIBERNATE);
    public void anadirEvento(Evento e){
           EventoDAO eventoDAO = dAOFactory.getEventoDAO();
           eventoDAO.anadirEvento(e);
    }
    public void anadirNacimiento(Nodo n){
         EventoDAO eventoDAO = dAOFactory.getEventoDAO();
         Evento evento = new Evento();
         evento.setFecha(n.getFechaNacimiento());
         String nombre = "Cumpleaños de "+ n.getNombre()+" "+n.getPrimerApellido()+" "+n.getSegundoApellido();
         evento.setNombre(nombre);
         evento.setNodo(n);
         eventoDAO.anadirEvento(evento);
    }
    public void anadirDefuncion(Nodo n){
         EventoDAO eventoDAO = dAOFactory.getEventoDAO();
         Evento evento = new Evento();
         evento.setFecha(n.getFechaDefuncion());
         String nombre = "Defuncion de "+ n.getNombre()+" "+n.getPrimerApellido()+" "+n.getSegundoApellido();
         evento.setNombre(nombre);
         evento.setNodo(n);
         eventoDAO.anadirEvento(evento);
    }
    
    public void actualizaNacimiento(Nodo n){
         EventoDAO eventoDAO = dAOFactory.getEventoDAO();
         Evento evento = new Evento();
         evento.setFecha(n.getFechaNacimiento());
         String nombre = "Cumpleaños de "+ n.getNombre()+" "+n.getPrimerApellido()+" "+n.getSegundoApellido();
         evento.setNombre(nombre);
         evento.setNodo(n);
         eventoDAO.actualizaEvento(evento);
    }
    public void actualizaDefuncion(Nodo n){
         EventoDAO eventoDAO = dAOFactory.getEventoDAO();
         Evento evento = new Evento();
         evento.setFecha(n.getFechaDefuncion());
         String nombre = "Aniversario de muerte de "+ n.getNombre()+" "+n.getPrimerApellido()+" "+n.getSegundoApellido();
         evento.setNombre(nombre);
         evento.setNodo(n);
         eventoDAO.actualizaEvento(evento);
    }
    public List<Evento> getAll(){
        EventoDAO eventoDAO = dAOFactory.getEventoDAO();
        List<Evento> l = new ArrayList<Evento>();
        l = eventoDAO.findAll();
        return l;
    }
    
    public List<Evento> getEventosPorIdArbol(String idArbol){
        EventoDAO eventoDAO = dAOFactory.getEventoDAO();
        List<Evento> l = new ArrayList<Evento>();
        l= eventoDAO.getEventosPorIdArbol(idArbol);
        return l;
    }
    
    public File creaCalendario(String ruta, String idArbol){
        List<Evento> eventos = getEventosPorIdArbol(idArbol);
        Calendar calendar = new Calendar();
        calendar.getProperties().add(new ProdId("calendario"));
        calendar.getProperties().add(Version.VERSION_2_0);
        calendar.getProperties().add(CalScale.GREGORIAN);
        
        try{
            for (Evento evento : eventos) {
                java.util.Calendar calAux = new GregorianCalendar();
                calAux.set(java.util.Calendar.MONTH, evento.getFecha().get(java.util.Calendar.MONTH));
                calAux.set(java.util.Calendar.DAY_OF_MONTH, evento.getFecha().get(java.util.Calendar.DAY_OF_MONTH));
                calAux.set(java.util.Calendar.YEAR, evento.getFecha().get(java.util.Calendar.YEAR));
                VEvent e = new VEvent(new Date(calAux.getTime()), evento.getNombre());
                 UidGenerator uidGenerator = new UidGenerator("1");
                 e.getProperties().add(uidGenerator.generateUid());
                 String n = evento.getNombre();
                 if (n.toLowerCase().contains("cumpleaños")){
                      
                     
                     Recur recur = new Recur(Recur.YEARLY,null);
                     RRule rule = new RRule(recur);
                     e.getProperties().add(rule);
                     
                 }
                calendar.getComponents().add(e);
            } 
            
       
        }
        
          //  Logger.getLogger(EventoBO.class.getName()).log(Level.SEVERE, null, ex);
        //}   
        catch(SocketException e){
            e.printStackTrace();
            }
       catch(NoClassDefFoundError e){
         e.printStackTrace();
       }
        catch(NoSuchElementException ne){
            String s = ne.getMessage();
        }
        
        File f2 = null;
        File fzip = null;
        try{
        File f = new File(ruta);
        f2 = File.createTempFile("calendario", ".ics",f);
        fzip = File.createTempFile("calendarioZip",".zip", f);
        
        
        
        FileOutputStream fout = new  FileOutputStream(f2);
        CalendarOutputter outputter = new CalendarOutputter();
        outputter.output(calendar, fout);
        
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(fzip));
        FileInputStream fileInputStream = new FileInputStream(f2.getPath());
        out.putNextEntry(new ZipEntry(f2.getName()));
        int len;
        byte[] buf = new byte[1024];
        while ((len = fileInputStream.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        out.closeEntry();        
        fileInputStream.close();
        out.close();
        
        }
       
        catch(IOException e){
            e.printStackTrace();
        }
        catch(ValidationException e){
            e.printStackTrace();
        }
        
        return fzip;
    }
    
    public File creaXmlCalendario(String idArbol){
        File file = null;
        try {
            Element raiz = new Element("calendario");
            List<Evento> eventos = getEventosPorIdArbol(idArbol);
            file = File.createTempFile("calendario", ".xml");
            for (Evento evento : eventos) {
                java.util.Calendar fechaC = evento.getFecha();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
                fechaC.set(java.util.Calendar.YEAR, java.util.Calendar.getInstance().get(java.util.Calendar.YEAR));                
                fechaC.set(java.util.Calendar.MONTH, fechaC.get(java.util.Calendar.MONTH) - 1);
                String fechaS = simpleDateFormat.format(fechaC.getTime());
                String nom = evento.getNombre();
                Element e = new Element("cita");
                e.setAttribute("fecha", fechaS);
                e.setAttribute("titulo", nom);
                raiz.addContent(e);
            }

            Document document = new Document(raiz);
            
            try {
                XMLOutputter out = new XMLOutputter();
                out.getFormat().setEncoding("iso-8859-1");
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                out.output(document, fileOutputStream);
                fileOutputStream.flush();
                fileOutputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
             } catch (IOException ex) {
            Logger.getLogger(EventoBO.class.getName()).log(Level.SEVERE, null, ex);
        }
            return file;
       
        
    }
    
    
}
